// 3. 观察者模式与发布订阅者区别，并写出其模型
// 答案详见：https://github.com/LuckyWinty/fe-weekly-questions/issues/49

class Emitter {
    constructor() {
        this.cache = {};
    }
    on(event, fn) {
        this.cache[event].push(fn)
    }
    emit(event, ...args) {
        this.cache[event].forEach(fn => fn(...args))
    }
    off(event, fn) {
        this.cache[event].filter(func => func !== fn)
    }
    once(event, fn) {
        function wrapFn(...args) {
            this.off(event, wrapFn)
            fn.call(this, ...args)
        }
        this.on(event, wrapFn)
    }

}

// https://zhuanlan.zhihu.com/p/81756807
// https://segmentfault.com/a/1190000022110467#item-2-11